{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Uncertainty calculation for model: SoilCarbon"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# import the libraries\n",
    "import ee\n",
    "import pandas as pd\n",
    "import os\n",
    "import numpy as np\n",
    "import random\n",
    "from random import sample\n",
    "import itertools \n",
    "import geopandas as gpd\n",
    "from sklearn.metrics import r2_score\n",
    "from termcolor import colored # this is allocate colour and fonts type for the print title and text\n",
    "from IPython.display import display, HTML"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "#set the working directory of local drive for Grid search result table loading\n",
    "# os.getcwd()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# initialize the earth engine API\n",
    "ee.Initialize()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1 Load the required composites, images and settings"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "# load the basic maps that needed for the analysis\n",
    "# load the two composites tha will be used in the analysis\n",
    "compositeImage =ee.Image(\"users/leonidmoore/ForestBiomass/20200915_Forest_Biomass_Predictors_Image\")\n",
    "compositeImageNew = ee.Image(\"projects/crowtherlab/Composite/CrowtherLab_Composite_30ArcSec\")\n",
    "# load the biome layer \n",
    "biomeLayer = compositeImage.select(\"WWF_Biome\")\n",
    "biomeMask = biomeLayer.mask(biomeLayer.neq(98)).mask(biomeLayer.neq(99)).gt(0)\n",
    "# define a pixel area layer with unit km2\n",
    "pixelAreaMap = ee.Image.pixelArea().divide(10000)\n",
    "# define the boundary geography reference\n",
    "unboundedGeo = ee.Geometry.Polygon([-180, 88, 0, 88, 180, 88, 180, -88, 0, -88, -180, -88], None, False)\n",
    "# define the standard projection\n",
    "stdProj = biomeLayer.projection()\n",
    "\n",
    "# load the present and potential forest cover\n",
    "presentForestCover = compositeImage.select('PresentTreeCover').unmask() # uniform with potential in the  0-1 scale\n",
    "potentialForestCover = ee.Image(\"users/leonidmoore/ForestBiomass/Bastin_et_al_2019_Potential_Forest_Cover_Adjusted\").unmask().rename('PotentialForestCover')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2 Load the soil carbon maps and apply the calculation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# load the carbon density layers\n",
    "SandermannCarbonDiff = ee.Image(\"users/leonidmoore/ForestBiomass/SoilOrganicCarbonModel/SOCS_0_200cm_Diff_1km_Present_subtract_NoLU\").unmask()\n",
    "SandermannCarbonPresent = ee.Image(\"users/leonidmoore/ForestBiomass/SoilOrganicCarbonModel/SOCS_0_200cm_1km_Present\").unmask()\n",
    "\n",
    "# mask the diffrence layer\n",
    "SandermannCarbonLoss = SandermannCarbonDiff.multiply(SandermannCarbonDiff.gt(0))\n",
    "\n",
    "# load the present and potential forest cover\n",
    "presentForestCover = compositeImage.select('PresentTreeCover').unmask() # uniform with potential in the  0-1 scale\n",
    "potentialCoverAdjusted = ee.Image(\"users/leonidmoore/ForestBiomass/Bastin_et_al_2019_Potential_Forest_Cover_Adjusted\").unmask().rename('PotentialForestCover')\n",
    "# define the present and potential forest cover masks\n",
    "presentMask = presentForestCover.gt(0)\n",
    "potentialMask = potentialCoverAdjusted.gte(0.1)\n",
    "\n",
    "# calculate the sum of the potential in soil with the consideration of forest cover\n",
    "SandermannCarbonStockLoss = SandermannCarbonLoss.multiply(pixelAreaMap).divide(1000000000).mask(biomeMask).mask(potentialMask).multiply(potentialCoverAdjusted)\n",
    "\n",
    "# SandermannCarbonStockLossResult =SandermannCarbonStockLoss.reduceRegion(reducer = ee.Reducer.sum(),\n",
    "#                                                                         geometry = unboundedGeo,\n",
    "#                                                                         crs = 'EPSG:4326',\n",
    "#                                                                         crsTransform = [0.008333333333333333,0,-180,0,-0.008333333333333333,90],\n",
    "#                                                                         maxPixels = 1e9)\n",
    "\n",
    "# print('Soil potential sum',SandermannCarbonStockLossResult.getInfo())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "SandermannCarbonLossLower = ee.Image(\"users/leonidmoore/ForestBiomass/SoilOrganicCarbonModel/SOCS_0_200cm_Diff_1km_Present_subtract_NoLU_Lower\").unmask()\n",
    "SandermannCarbonLossUpper = ee.Image(\"users/leonidmoore/ForestBiomass/SoilOrganicCarbonModel/SOCS_0_200cm_Diff_1km_Present_subtract_NoLU_Upper\").unmask()\n",
    "\n",
    "SandermannCarbonStockLossLower = SandermannCarbonLossLower.multiply(pixelAreaMap).divide(1000000000).mask(biomeMask).mask(potentialMask).multiply(potentialCoverAdjusted)\n",
    "SandermannCarbonStockLossUpper = SandermannCarbonLossUpper.multiply(pixelAreaMap).divide(1000000000).mask(biomeMask).mask(potentialMask).multiply(potentialCoverAdjusted)\n",
    "\n",
    "# SandermannCarbonStockLowerResult =SandermannCarbonStockLossLower.reduceRegion(reducer = ee.Reducer.sum(),\n",
    "#                                                                         geometry = unboundedGeo,\n",
    "#                                                                         crs = 'EPSG:4326',\n",
    "#                                                                         crsTransform = [0.008333333333333333,0,-180,0,-0.008333333333333333,90],\n",
    "#                                                                         maxPixels = 1e9)\n",
    "\n",
    "# print('Soil potential lower sum',SandermannCarbonStockLowerResult.getInfo())\n",
    "\n",
    "# SandermannCarbonStockUpperResult =SandermannCarbonStockLossUpper.reduceRegion(reducer = ee.Reducer.sum(),\n",
    "#                                                                         geometry = unboundedGeo,\n",
    "#                                                                         crs = 'EPSG:4326',\n",
    "#                                                                         crsTransform = [0.008333333333333333,0,-180,0,-0.008333333333333333,90],\n",
    "#                                                                         maxPixels = 1e9)\n",
    "\n",
    "# print('Soil potential upper sum',SandermannCarbonStockUpperResult.getInfo())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3 Partioning the potential cover into different landuse types"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Load all the landuse type layers\n",
    "croplandOrg = ee.Image(\"users/leonidmoore/ForestBiomass/HYDE31/cropland_Percent\").rename('cropland').divide(100).reproject(crs=stdProj);\n",
    "grazingOrg = ee.Image(\"users/leonidmoore/ForestBiomass/HYDE31/grazing_Percent\").rename('grazing').divide(100).reproject(crs=stdProj);\n",
    "pastureOrg = ee.Image(\"users/leonidmoore/ForestBiomass/HYDE31/pasture_Percent\").rename('pasture').divide(100).reproject(crs=stdProj);\n",
    "rangelandOrg = ee.Image(\"users/leonidmoore/ForestBiomass/HYDE31/rangeland_Percent\").rename('rangeland').divide(100).reproject(crs=stdProj);\n",
    "urbanOrg = compositeImage.select(['LandCoverClass_Urban_Builtup']).divide(100).unmask().reproject(crs=stdProj);\n",
    "snowIceOrg = compositeImageNew.select(['ConsensusLandCoverClass_Snow_Ice']).divide(100).unmask().reproject(crs=stdProj);\n",
    "openWaterOrg = compositeImageNew.select(['ConsensusLandCoverClass_Open_Water']).divide(100).unmask().reproject(crs=stdProj);\n",
    "# define the total landcover types\n",
    "sumCover = presentForestCover.add(pastureOrg).add(rangelandOrg).add(croplandOrg).add(urbanOrg).add(openWaterOrg).add(snowIceOrg);\n",
    "oneSubtract = ee.Image(1).subtract(sumCover);\n",
    "freeland = oneSubtract.multiply(oneSubtract.gte(0));\n",
    "# get the scale ratio for pixels with sumCover larger than 1\n",
    "scaleRatio = ee.Image(1).subtract(presentForestCover).divide(sumCover.subtract(presentForestCover)).multiply(oneSubtract.lt(0));\n",
    "# get the ratio of these three disturbed maps\n",
    "pasture = pastureOrg.multiply(scaleRatio).multiply(oneSubtract.lt(0)).add(pastureOrg.multiply(oneSubtract.gte(0))).unmask();\n",
    "rangeland = rangelandOrg.multiply(scaleRatio).multiply(oneSubtract.lt(0)).add(rangelandOrg.multiply(oneSubtract.gte(0))).unmask();\n",
    "cropland = croplandOrg.multiply(scaleRatio).multiply(oneSubtract.lt(0)).add(croplandOrg.multiply(oneSubtract.gte(0))).unmask();\n",
    "urban = urbanOrg.multiply(scaleRatio).multiply(oneSubtract.lt(0)).add(urbanOrg.multiply(oneSubtract.gte(0))).unmask();\n",
    "openWater = openWaterOrg.multiply(scaleRatio).multiply(oneSubtract.lt(0)).add(openWaterOrg.multiply(oneSubtract.gte(0))).unmask();\n",
    "snowIce = snowIceOrg.multiply(scaleRatio).multiply(oneSubtract.lt(0)).add(snowIceOrg.multiply(oneSubtract.gte(0))).unmask();\n",
    "sumTT = presentForestCover.add(pasture).add(rangeland).add(cropland).add(urban).add(freeland).add(openWater).add(snowIce).unmask();\n",
    "\n",
    "effectivePotentialMask = freeland.add(rangeland).add(pasture).add(cropland).add(urban).gt(0);\n",
    "# there are some pixels without any landcover survived but with open water and ice and snow. here we mask these pixels out\n",
    "sumlandCover = pastureOrg.add(rangelandOrg).add(croplandOrg).add(urbanOrg).add(freeland);\n",
    "restorationMap = potentialCoverAdjusted.subtract(presentForestCover).mask(effectivePotentialMask).unmask();\n",
    "\n",
    "# sum all these scaled layersv\n",
    "scaledSum = pasture.add(rangeland).add(cropland).add(urban).add(freeland);\n",
    "potentialCoverFinal = restorationMap.add(presentForestCover);\n",
    "# allocate the potential equally to each layer\n",
    "freelandPotentialCover = freeland.divide(scaledSum).multiply(restorationMap).unmask();\n",
    "rangelandPotentialCover = rangeland.divide(scaledSum).multiply(restorationMap).unmask();\n",
    "pasturePotentialCover = pasture.divide(scaledSum).multiply(restorationMap).unmask();\n",
    "croplandPotentialCover = cropland.divide(scaledSum).multiply(restorationMap).unmask();\n",
    "urbanPotentialCover = urban.divide(scaledSum).multiply(restorationMap).unmask();\n",
    "#  allocate the freeland potential in pixels with forest cover larger than 10% to conservation potential\n",
    "freelandForConsevation = freelandPotentialCover.multiply(presentForestCover.gte(0.1)).unmask();\n",
    "maximumPotentialCover = freelandForConsevation.add(presentForestCover);\n",
    "# calucate the reall freeland outside of forest\n",
    "freelandLeftMap = freelandPotentialCover.subtract(freelandForConsevation).unmask()# the left positive pixels are real freeland pixels"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3 Calculate the Upper and Lower of soil carbon potential"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[1m\u001b[34mThe Soil carbon and potential uncertaintt partition results in biome: \n",
      "\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>SoilCarbon</th>\n",
       "      <th>SoilCarbonLower</th>\n",
       "      <th>SoilCarbonUpper</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>12.904557</td>\n",
       "      <td>6.449871</td>\n",
       "      <td>31.872728</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1.936013</td>\n",
       "      <td>1.153363</td>\n",
       "      <td>3.080229</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0.618024</td>\n",
       "      <td>0.304301</td>\n",
       "      <td>1.114871</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>15.119911</td>\n",
       "      <td>8.896084</td>\n",
       "      <td>28.705624</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1.771906</td>\n",
       "      <td>0.662486</td>\n",
       "      <td>6.732126</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>1.448459</td>\n",
       "      <td>0.410863</td>\n",
       "      <td>27.185123</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>7.517337</td>\n",
       "      <td>4.558406</td>\n",
       "      <td>11.735743</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>3.732073</td>\n",
       "      <td>2.027256</td>\n",
       "      <td>6.807501</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>0.452222</td>\n",
       "      <td>0.294886</td>\n",
       "      <td>0.739886</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>0.816784</td>\n",
       "      <td>0.376503</td>\n",
       "      <td>1.755809</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>0.078180</td>\n",
       "      <td>0.007665</td>\n",
       "      <td>4.221751</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>1.008690</td>\n",
       "      <td>0.453287</td>\n",
       "      <td>1.843983</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>1.501596</td>\n",
       "      <td>0.971286</td>\n",
       "      <td>2.200511</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>0.399405</td>\n",
       "      <td>0.262225</td>\n",
       "      <td>0.681193</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>sum</th>\n",
       "      <td>49.305157</td>\n",
       "      <td>26.828481</td>\n",
       "      <td>128.677078</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     SoilCarbon  SoilCarbonLower  SoilCarbonUpper\n",
       "0     12.904557         6.449871        31.872728\n",
       "1      1.936013         1.153363         3.080229\n",
       "2      0.618024         0.304301         1.114871\n",
       "3     15.119911         8.896084        28.705624\n",
       "4      1.771906         0.662486         6.732126\n",
       "5      1.448459         0.410863        27.185123\n",
       "6      7.517337         4.558406        11.735743\n",
       "7      3.732073         2.027256         6.807501\n",
       "8      0.452222         0.294886         0.739886\n",
       "9      0.816784         0.376503         1.755809\n",
       "10     0.078180         0.007665         4.221751\n",
       "11     1.008690         0.453287         1.843983\n",
       "12     1.501596         0.971286         2.200511\n",
       "13     0.399405         0.262225         0.681193\n",
       "sum   49.305157        26.828481       128.677078"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Stack the absolute biomass layers into an Image.\n",
    "absPotentialImage = SandermannCarbonStockLoss.rename('SoilCarbon').addBands(SandermannCarbonStockLossLower.rename('SoilCarbonLower')).addBands(SandermannCarbonStockLossUpper.rename('SoilCarbonUpper'))\n",
    "\n",
    "# define the function to do the biome level statistics which could be applied by map      \n",
    "def biomeLevelStat(biome):\n",
    "    perBiomeMask = biomeLayer.eq(ee.Number(biome))\n",
    "    masked_img = absPotentialImage.mask(perBiomeMask)\n",
    "    output = masked_img.reduceRegion(reducer= ee.Reducer.sum(),\n",
    "                                     geometry= unboundedGeo,\n",
    "                                     crs='EPSG:4326',\n",
    "                                     crsTransform=[0.008333333333333333,0,-180,0,-0.008333333333333333,90],\n",
    "                                     maxPixels= 1e13)\n",
    "    return output#.getInfo().get('Present')\n",
    "\n",
    "\n",
    "biomeList = ee.List([1,2,3,4,5,6,7,8,9,10,11,12,13,14])\n",
    "statisticTable = biomeList.map(biomeLevelStat).getInfo()\n",
    "# transform into data frame\n",
    "outputTable = pd.DataFrame(statisticTable,columns =['SoilCarbon','SoilCarbonLower','SoilCarbonUpper'])#.round(1)\n",
    "outputTable.loc['sum'] = outputTable.sum() \n",
    "outputTable.to_csv('Data/BiomeLevelStatistics/StatisticsForModels/SoilCarbon_Uncertainty_for_diff_parts_at_Biome_Level.csv',header=True,mode='w+')\n",
    "print(colored('The Soil carbon and potential uncertaintt partition results in biome: \\n', 'blue', attrs=['bold']))\n",
    "outputTable.head(15)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[1m\u001b[34mThe Soil carbon uncertainty partition results in biome: \n",
      "\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Types</th>\n",
       "      <th>ConservationPotential</th>\n",
       "      <th>AbsolutePotential</th>\n",
       "      <th>FreelandPotential</th>\n",
       "      <th>RangelandPotential</th>\n",
       "      <th>PasturePotential</th>\n",
       "      <th>CroplandPotential</th>\n",
       "      <th>UrbanPotential</th>\n",
       "      <th>FreeToConservation</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>SoilCarbon</td>\n",
       "      <td>27.343209</td>\n",
       "      <td>49.305157</td>\n",
       "      <td>4.154445</td>\n",
       "      <td>3.073412</td>\n",
       "      <td>5.967752</td>\n",
       "      <td>8.486939</td>\n",
       "      <td>0.278854</td>\n",
       "      <td>3.394090</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>SoilCarbonLower</td>\n",
       "      <td>13.474602</td>\n",
       "      <td>26.828481</td>\n",
       "      <td>2.385280</td>\n",
       "      <td>1.883432</td>\n",
       "      <td>3.487478</td>\n",
       "      <td>5.425776</td>\n",
       "      <td>0.171845</td>\n",
       "      <td>1.610869</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>SoilCarbonUpper</td>\n",
       "      <td>91.084407</td>\n",
       "      <td>128.677078</td>\n",
       "      <td>10.522030</td>\n",
       "      <td>4.643033</td>\n",
       "      <td>9.367126</td>\n",
       "      <td>12.578619</td>\n",
       "      <td>0.456830</td>\n",
       "      <td>12.325133</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "             Types  ConservationPotential  AbsolutePotential  \\\n",
       "0       SoilCarbon              27.343209          49.305157   \n",
       "1  SoilCarbonLower              13.474602          26.828481   \n",
       "2  SoilCarbonUpper              91.084407         128.677078   \n",
       "\n",
       "   FreelandPotential  RangelandPotential  PasturePotential  CroplandPotential  \\\n",
       "0           4.154445            3.073412          5.967752           8.486939   \n",
       "1           2.385280            1.883432          3.487478           5.425776   \n",
       "2          10.522030            4.643033          9.367126          12.578619   \n",
       "\n",
       "   UrbanPotential  FreeToConservation  \n",
       "0        0.278854            3.394090  \n",
       "1        0.171845            1.610869  \n",
       "2        0.456830           12.325133  "
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# stack the uncertainty maps to an image\n",
    "intervalImage = ee.List([SandermannCarbonLoss,\n",
    "                         SandermannCarbonLossLower,\n",
    "                         SandermannCarbonLossUpper])\n",
    "\n",
    "coversImage = maximumPotentialCover.rename('ConservationPotential').addBands(potentialForestCover.rename('AbsolutePotential')).addBands(freelandLeftMap.rename('FreelandPotential')).addBands(rangelandPotentialCover.rename('RangelandPotential')).addBands(pasturePotentialCover.rename('PasturePotential')).addBands(croplandPotentialCover.rename('CroplandPotential')).addBands(urbanPotentialCover.rename('UrbanPotential')).addBands(freelandForConsevation.rename('FreeToConservation'))\n",
    "\n",
    "def landtypeUncertainPotential(perImage):\n",
    "    absImage = coversImage.multiply(perImage).multiply(pixelAreaMap).multiply(potentialMask).multiply(biomeMask).divide(1000000000)\n",
    "    output = absImage.reduceRegion(reducer= ee.Reducer.sum(),\n",
    "                                   geometry= unboundedGeo,\n",
    "                                   crs='EPSG:4326',\n",
    "                                   crsTransform=[0.008333333333333333,0,-180,0,-0.008333333333333333,90],\n",
    "                                   maxPixels= 1e13)\n",
    "    return output#.getInfo().get('Present')\n",
    "\n",
    "\n",
    "statisticTable = intervalImage.map(landtypeUncertainPotential).getInfo()\n",
    "# transform into data frame\n",
    "outputTable = pd.DataFrame(statisticTable,columns =['Types','ConservationPotential','AbsolutePotential','FreelandPotential','RangelandPotential','PasturePotential','CroplandPotential','UrbanPotential','FreeToConservation'])#.round(1)\n",
    "# allocate the row names into the 'Types' column\n",
    "finalTablePotential = outputTable.assign(Types=['SoilCarbon',\n",
    "                                                'SoilCarbonLower',\n",
    "                                                'SoilCarbonUpper'])\n",
    "\n",
    "# write the result into local folder \n",
    "finalTablePotential.to_csv('Data/BiomeLevelStatistics/StatisticsForModels/SoilCarbon_Landuse_type_Uncertainty.csv',header=True,mode='w+')\n",
    "print(colored('The Soil carbon uncertainty partition results in biome: \\n', 'blue', attrs=['bold']))\n",
    "# print the data frame of the results\n",
    "finalTablePotential.head(3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [],
   "source": [
    "# If you got the error 'EEException: Too many concurrent aggregations.', please re-run this chunck of code again."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
